package com.spring.aop.validate;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.spring.aop.utils.ReflectionUtils;

/**
 * 数据验证
 * 验证对象被边有注解的属性，并通过递归方式验证对象里的集合
 * @author K
 *
 */
public class ValidatorData {
	private static Logger logger = LoggerFactory.getLogger(ValidatorData.class);

	public void doBefore(JoinPoint joinPoint) {
		//获取拦截的方法传入的参数
		Object[] array = joinPoint.getArgs();
		Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
		for (int i = 0; i < array.length; i++) {
			if (array[i] instanceof List) {
				this.validateList(validator, (List<Object>) array[i]);
			} else {
				// 验证对象
				this.validateObject(validator, array[i]);
			}
		}
	}
	
	private void validateObject(Validator validator, Object object) {
		Field[] fields = object.getClass().getDeclaredFields();
		for (Field field : fields) {
			Class<?> clazz = field.getType();
			if (clazz.equals(List.class)) {
				List<Object> tmp = (List<Object>) ReflectionUtils.invokeGetterMethod(object, field.getName());
				for (Object obj : tmp) {
					//递归验证集合里的对象属性
					this.validateObject(validator, obj);
				}
			}
		}
		
		// 验证某个对象,，其实也可以只验证其中的某一个属性的
		Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object);
		for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
			logger.warn(constraintViolation.getPropertyPath() + ": " + constraintViolation.getMessage());
		}
	}
	
	private void validateList(Validator validator, List<Object> list) {
		for (Object obj : list) {
			this.validateObject(validator, obj);
		}
	}
}
